﻿#pragma once

#include <learn/ais/ais_context.h>
#include <learn/painter/painter3d.h>
#include <learn/painter/renderer.h>
#include <learn/painter/shader.h>

#include <functional>

namespace xi
{

namespace painter
{

using namespace xi::ais;

class EXT_SYMBOL Paint_Context
{
  public:
    enum Texture
    {
        Yellow2d,
        White2d,
        Red2d,
        Green2d,
        Blue2d,
        Black2d,
        Chess,
        Dash,
        Snipple,
        Background
    };

    struct Current
    {
        VAO vao;                        // 当前顶点数组对象
        VBO vbo;                        // 当前顶点缓冲对象
        EBO ebo;                        // 当前索引缓冲对象
        std::shared_ptr<Shader> shader; // 当前着色器
    };

    /**
     * @brief 构建上下文
     *
     * @param[in] width
     * @param[in] height
     */
    Paint_Context(int width, int height, std::function<void(const Paint_Context *)> initProc,
                  std::function<void(const Paint_Context *)> dealProc);

    /**
     * @brief 生成着色器
     *
     * @param[in] i
     * @param[in] shader
     */
    void gen_shader(std::string i, std::shared_ptr<Shader> shader);

    /**
     * @brief 绑定着色器
     *
     * @param[in] i
     * @return true
     * @return false
     */
    bool bind_shader(std::string i);

    /**
     * @brief 加载顶点数据
     *
     * @param[in] i
     */
    void gen_array(int i);

    /**
     * @brief 绑定顶点数据
     *
     * @param[in] i
     * @return true
     * @return false
     */
    bool bind_array(int i);

    /**
     * @brief 加载 2D 纹理
     *
     * @param[in] file
     */
    void load_tex2d(const char *file);

    /**
     * @brief 加载 2D 纹理
     *
     * @param[in] texture
     */
    void load_tex2d(Texture texture);

    /**
     * @brief 修改尺寸
     *
     * @param[in] width
     * @param[in] height
     */
    void resize_event(int width, int height);

    /**
     * @brief 绘制
     *
     */
    TGA_Image paint_event() const;

    /**
     * @brief 获得当前上下文的数据
     *
     * @return Current
     */
    Current current() const;

    /**
     * @brief 获得 AIS_Context
     *
     * @return std::shared_ptr<AIS_Context>
     */
    std::shared_ptr<AIS_Context> context() const;

    /**
     * @brief 获得画家
     *
     * @return std::shader_ptr<Painter3D>
     */
    std::shared_ptr<Painter3D> painter() const;

  protected:
    std::shared_ptr<Painter3D> m_painter;      // 画家
    std::shared_ptr<AIS_Context> m_aisContext; // 交互式系统上下文
    Current m_current;                         // 当前上下文数据

    std::map<int, VAO> m_VAOs;                                // 顶点数组对象
    std::map<int, VBO> m_VBOs;                                // 顶点缓冲对象
    std::map<int, EBO> m_EBOs;                                // 索引缓冲对象
    std::map<std::string, std::shared_ptr<Shader>> m_shaders; // 保存着色器
    std::vector<TGA_Image> m_textures;                        // 2D 纹理

    std::function<void(const Paint_Context *)> m_initProc; // 初始化过程
    std::function<void(const Paint_Context *)> m_dealProc; // 处理过程
};

} // namespace painter

} // namespace xi
